/*
  this file contains some generic functions that don't
  really fit in any particular classes
*/

// simply returns if a variable is array
function isArray( mixed_var ) {

    return ( mixed_var instanceof Array );

}

// sorts the type and id from just an id or from type and mixed id (e.g. if you had an id of "folder:10348" it would return "folder" as type and "10348" as id)
function sortTypeId(type,id) {

    back = [];

    if (type == "unknown") {

      var split = [];
      split = id.split(':');
      back[0] = split[0].toLowerCase();
      back[1] = split[1];
      
      if(split.length>2) {
        back[2] = split[2];
      } else {
        back[2] = "";
      }
      
    
    } else {
    
      back[0] = type.toLowerCase();
      back[1] = id;
      back[2] = "";
    
    }
    
    return back;

}

// counts the number of a certain letter occurring in the string
// used in making display names for list elements
function countletters(letter, string) {

  count = 0;
  
  var i = 0;
  
  for (i = 0; i < string.length; i++) {
  
    if (string.charAt(i) == letter) {
    
      count = count + 1;
      
    }
  
  }

  return count;

}

// returns an icon filename for file extensions
function getIcon(type) {

  icon = "unknown";

  if (type.lastIndexOf(".") != -1) {
  
    pos = type.lastIndexOf(".");
    
    type = type.substr(pos+1);
  
  }

  switch(type) {
  
    // workspace
    case "workspace":
      icon = "workspace";
      break;
  
    // folder
    case "Folder":
      icon = "folder";
      break;
    
    // word
    case "doc":
    case "docx":
    case "odt":
      icon = "doc";
      break;
      
    // excel
    case "xls":
    case "xlsx":
    case "ods":
      icon = "xls";
    
    // powerpoint
    case "ppt":
    case "pptx":
    case "odp":
      icon = "ppt";
      break;
      
    // pdf
    case "pdf":
      icon = "pdf";
      break;
      
    // image
    case "jpg":
    case "jpeg":
    case "png":
    case "bmp":
    case "psd":
    case "ai":
    case "gif":
    case "ps":
    case "psp":
    case "svg":
    case "tif":
    case "tiff":
      icon = "img";
      break;
    
    // sound
    case "aac":
    case "aif":
    case "m3u":
    case "mid":
    case "midi":
    case "mp3":
    case "mpa":
    case "ra":
    case "ram":
    case "wav":
    case "wma":
      icon = "sound";
      break;
    
    // video
    case "3gp":
    case "avi":
    case "mov":
    case "mp4":
    case "mpg":
    case "qt":
    case "rm":
    case "wmv":
      icon = "video";
      break;
      
    // web
    case "asp":
    case "css":
    case "htm":
    case "html":
    case "js":
    case "jsp":
    case "php":
    case "xhtml":
    case "swf":
      icon = "web";
      break;
  
  }
  
  return icon;

}

// takes a really long title for workspace/folder/file etc and formats it nicely for display on the grid
function makeDisplayTitle(title) {

  linelimit = 11;
  
  result = "";
  dash = "";
  dots = "...";
  
  var i = 0;

  if (title.length > linelimit) {
  
    if (countletters("m",title) > 1) {
    
      linelimit = 9;
    
    }
  
    part1 = "";
    part2 = "";
    
    br = "<BR>";
    
    for (i = -3; i <= 1; i++) {
    
      position = linelimit + i;
    
      if (title.charAt(position) == " ") {
    
        if (part1=="") {
        
          part1 = title.substring(0,position);
          
          br = " ";
        
        }
      
        part2 = title.substring(position+1);
      
      }
    
    }
   
    if (part2 == "") {
    
      part1 = title.substring(0,linelimit);
      
      dash = "-";
      
      if (title.substring(linelimit)) {
      
        part2 = title.substring(linelimit);
        
      }
    
    }
    
    if (part2.length > linelimit) {
    
      part2 = part2.substring(0,linelimit-1) + dots;
    
    }
    
    result = "<span>" + part1 + dash + br + part2 + "</span>";

    title = result;
    
    modified = 1;
  
  } else {
  
    title = "<span>" + title + "</span><BR>&nbsp;";
    
    modified = 0;
    
  }
  
  returner = new Array(title, modified);
 
  return returner;

}

// class for each element (or <li>) of the display list
function Cell() {

  // initialise properties for the cell
  this.id = "";
  this.objectId = "";
  this.imageId = "";
  this.titleId = "";
  this.formattedName = "";
  this.name = "";
  this.type = "";
  this.image = "";
  this.clicked = false;
  
  // called to set the variables for the cell
  this.init = function(input) {
  
    this.id = input.Id;
  
    if (input.Type==undefined) {
    
      this.type = "workspace";
    
    } else {
    
      this.type = input.Type;
    
    }
    
    this.type = this.type.toLowerCase();
    
    this.objectId = this.type + ":" + this.id;
    
    this.imageId = "img:" + this.id;
    
    if (input.FileName) {
    
      this.image = getIcon(input.FileName);
    
    } else if (input.Type) {
    
      this.image = getIcon(input.Type);
    
    } else {
    
      this.image = getIcon("workspace");
      
    }
    
    this.name = input.Title;
    
    this.formattedName = makeDisplayTitle(input.Title);
    
    this.formattedName = this.formattedName[0]; // gets rid of any arrays
  
  }
  
  // returns the code for this cell using its properties
  this.code = function() {
  
    return "<li id='" + this.objectId + "'><span><img src='imgs/icons/" + this.image + "-50.png' class='elementimg' id='" + this.imageId + "'></span><p>" + this.formattedName + "</p></li>";
  
  }
  
  // adds appropriate listeners to the cell when called
  this.listeners = function(object) {
  
    /*
      the object passed is actually this instanciation of the class
      but it is required as inside addEventListener "this" doesn't
      point to the correct element and causes quite a few problems
    */
  
    // sets drag and drop properties if its the right type
    if (object.type == "folder") {
    
      drag.set(object.objectId);
    
    } else if (object.type == "file") {
    
      drag.set(object.objectId, "out");
    
    }
  
    // click
    document.getElementById(object.objectId).addEventListener("click", function() { 
    
      if ((window.isShiftDown) && (object.type == "file")) {

        selecter.toggle(object.id);
      
      } else if (!object.clicked) {
      
        if (object.type == "workspace") {
          dropdown.selected(object.id);
        } else if (object.type == "folder") {
          breadcrumbs.addCrumb(object.name,object.id);
        }
        
        page.displayPage("unknown", object.objectId);
        
        object.unlisten(object);
        
      }
      
    } , false);
      
    // mouseover
    document.getElementById(object.objectId).addEventListener("mouseover", function(event) { 
      
      if (selecter.is(object.id)) {
        colour = "#5b5b5b";
      } else {
        colour = "#d4d4d4";
      }
      document.getElementById(object.imageId).style.borderColor = colour;
      
      // this section displays the full title and formats correctly on mouse over
      document.getElementById(object.objectId).getElementsByTagName("p")[0].style.margin = "0px 0px 0px 3px";
      document.getElementById(object.objectId).getElementsByTagName("p")[0].style.margin = "0px 2px";
      document.getElementById(object.objectId).getElementsByTagName("p")[0].getElementsByTagName("span")[0].innerHTML = object.name;
      document.getElementById(object.objectId).getElementsByTagName("p")[0].style.position = "relative";
      document.getElementById(object.objectId).getElementsByTagName("p")[0].style.backgroundImage = "url(../imgs/bg/mouseover.png)"; 
    }, false);
    
    // mouse move
    document.getElementById(object.objectId).addEventListener("mousemove", function(event) {

      if (selecter.is(object.id)) {
        colour = "#5b5b5b";
      } else {
        colour = "#d4d4d4";
      }
      document.getElementById(object.imageId).style.borderColor = colour;
      // needed to stop the expanded element collapsing
      document.getElementById(object.objectId).getElementsByTagName("p")[0].style.width = "66px";
    }, false);
    
    // mouseout
    document.getElementById(object.objectId).addEventListener("mouseout", function() { 
      
      if (selecter.is(object.id)) {
        colour = "#5b5b5b";
      } else {
        colour = "#c7c7c7";
      }
      
      if(document.getElementById(object.imageId)) { // this stops a few little bugs when the element can't be found for some reason
        document.getElementById(object.imageId).style.borderColor = colour;
        // resets the extended title back to normal
        document.getElementById(object.objectId).getElementsByTagName("p")[0].innerHTML = object.formattedName;
        document.getElementById(object.objectId).getElementsByTagName("p")[0].style.width = "";
        document.getElementById(object.objectId).getElementsByTagName("p")[0].style.position = "";
        document.getElementById(object.objectId).getElementsByTagName("p")[0].style.margin = "0px";
        document.getElementById(object.objectId).getElementsByTagName("p")[0].style.padding = "0px";
        document.getElementById(object.objectId).getElementsByTagName("p")[0].style.backgroundImage = "none";
      }
      
    }, false);
  
  }
  
  // easily remove all listeners
  // also called after its been clicked to stop problems with double click
  this.unlisten = function(object) {

    object.clicked = true;

    drag.remove(object.objectId);
  
  }

}

// class to handle the grid as a whole
function Table() {

  // array of Cell objects representing grid
  this.array = [];
  this.isDashboard = false; // just so we can tell if its the dashboard or not
  
  // adds listeners to all the cells in the array
  this.listeners = function() {
  
    for (i = 0; i < this.array.length; i++) {
    
      this.array[i].listeners(this.array[i]);
    
    }
  
  }
  
  // returns code for the entire grid into the "target" element
  this.code = function(target) {
  
    code = "";
  
    if (!this.isDashboard) { // add breadcrumbs if its not the dashboard
    
      code = code + "<p id='breadcrumbs'></p>";
      
    }
  
    code = code + "<ul class='thumbnails'>";
    
    for (i = 0; i < this.array.length; i++) { // write in all the elements
    
      code = code + this.array[i].code();
    
    }
    
    code = code + "</ul>";
    
    $(target).append(code); // write the whole lot into the page
    
    if (!this.isDashboard) { // write in breadcrumbs if its not the dashboard
    
      breadcrumbs.write();
    
    }
    
    table.listeners(); // add all the listeners AFTER the code has been written to the page
  
  }
  
  // function to easily add new Cell
  this.add = function(item) {
      
    cell = new Cell;
    cell.init(item);
    
    if (item.Type == undefined) {
    
      this.isDashboard = true; // set dashboard if a workspace is detected
    
    }
    
    this.array.push(cell);
  
  }
  
  // add an array of items to the table
  this.addItems = function(items) {
  
    for (i = 0; i < items.length; i++) {
    
      this.add(items[i]);

    }
  
  }
  
  // easily wipe all the listeners in the table
  this.destroy = function() {
  
    for (x in this.array) {
    
      array[x].unlisten(array[x]);
    
    }
  
  }

}

// wrapper function for legacy's sake to easily make a table.
function makeTable(items) {

  table = new Table;
  table.addItems(items);

  table.code("#huddle>div>div");

}